#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <atomic>
#include <vector>
#include <string>
#include <stop_token>

// 展示C++20的std::jthread功能

// 用于演示的互斥锁
std::mutex output_mutex;

// 一个可停止的工作函数
void background_worker(std::stop_token token, int id, int sleep_ms) {
    int counter = 0;
    
    while (!token.stop_requested() && counter < 10) {
        {
            std::lock_guard<std::mutex> lock(output_mutex);
            std::cout << "  工作线程 #" << id << " - 第 " << counter 
                      << " 次迭代\n";
        }
        
        // 模拟工作
        std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms));
        counter++;
        
        // 检查是否请求终止
        if (token.stop_requested()) {
            std::lock_guard<std::mutex> lock(output_mutex);
            std::cout << "  工作线程 #" << id << " 收到终止请求\n";
        }
    }
    
    {
        std::lock_guard<std::mutex> lock(output_mutex);
        std::cout << "  工作线程 #" << id 
                  << (token.stop_requested() ? " 被终止" : " 正常完成") << "\n";
    }
}

// 带有停止回调的工作函数
void worker_with_callback(std::stop_token token, std::string name) {
    // 注册停止回调
    std::stop_callback callback(token, []() {
        std::lock_guard<std::mutex> lock(output_mutex);
        std::cout << "  停止回调执行中...\n";
    });
    
    while (!token.stop_requested()) {
        {
            std::lock_guard<std::mutex> lock(output_mutex);
            std::cout << "  " << name << " 正在运行...\n";
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }
    
    {
        std::lock_guard<std::mutex> lock(output_mutex);
        std::cout << "  " << name << " 线程结束\n";
    }
}

// 不同类型的工作函数，打印数字
void number_printer(std::stop_token token) {
    int number = 0;
    while (!token.stop_requested() && number < 20) {
        {
            std::lock_guard<std::mutex> lock(output_mutex);
            std::cout << "  数字: " << number << "\n";
        }
        number++;
        std::this_thread::sleep_for(std::chrono::milliseconds(300));
    }
}

void demonstrate_jthread() {
    using namespace std::chrono_literals;
    
    std::cout << "  C++20 std::jthread 演示:\n\n";
    
    // 1. 基本用法
    std::cout << "  1. 基本用法:\n";
    {
        std::cout << "  创建和自动清理jthread:\n";
        
        // 创建jthread
        std::jthread worker([]() {
            for (int i = 0; i < 3; ++i) {
                {
                    std::lock_guard<std::mutex> lock(output_mutex);
                    std::cout << "  基本jthread线程 - 迭代 " << i << "\n";
                }
                std::this_thread::sleep_for(std::chrono::milliseconds(200));
            }
        });
        
        // 无需调用join()，jthread会自动处理
        std::this_thread::sleep_for(std::chrono::milliseconds(700));
        std::cout << "  jthread会在作用域结束时自动join\n\n";
    }
    
    // 2. 停止线程功能
    std::cout << "  2. 停止线程功能:\n";
    {
        std::jthread worker(background_worker, 1, 300);
        
        // 让线程运行一段时间
        std::this_thread::sleep_for(1s);
        
        // 请求线程停止
        std::cout << "  主线程请求工作线程停止\n";
        worker.request_stop();
        
        // 等待线程结束
        std::cout << "  等待工作线程结束...\n";
    }
    std::cout << "  工作线程已停止\n\n";
    
    // 3. 多线程终止
    std::cout << "  3. 多线程终止:\n";
    {
        std::vector<std::jthread> workers;
        
        // 创建多个工作线程
        for (int i = 0; i < 3; ++i) {
            workers.emplace_back(background_worker, i+1, 200 + i*100);
        }
        
        // 让线程运行一段时间
        std::this_thread::sleep_for(1s);
        
        // 请求所有线程停止
        std::cout << "  主线程请求所有工作线程停止\n";
        for (auto& worker : workers) {
            worker.request_stop();
        }
        
        std::cout << "  线程将在作用域结束时自动联接\n";
    }
    std::cout << "  所有工作线程已停止\n\n";
    
    // 4. 停止回调
    std::cout << "  4. 停止回调:\n";
    {
        std::jthread worker(worker_with_callback, "回调演示线程");
        
        std::this_thread::sleep_for(1s);
        
        std::cout << "  主线程请求工作线程停止（将触发回调）\n";
        worker.request_stop();
    }
    std::cout << "  带回调的线程已停止\n\n";
    
    // 5. 与传统std::thread的比较
    std::cout << "  5. 与std::thread的比较:\n";
    std::cout << "  std::thread:\n";
    std::cout << "  - 需要手动调用join()或detach()\n";
    std::cout << "  - 没有内置的终止机制\n";
    std::cout << "  - 忘记调用join/detach会导致程序崩溃\n\n";
    
    std::cout << "  std::jthread:\n";
    std::cout << "  - 析构时自动调用join()\n";
    std::cout << "  - 内置的线程终止机制\n";
    std::cout << "  - 支持stop_token和停止回调\n";
    std::cout << "  - 更安全，不会因忘记join而崩溃\n\n";
    
    // 6. 实际应用
    std::cout << "  6. 实际应用场景:\n";
    {
        // 创建一个打印数字的线程
        std::jthread counter(number_printer);
        
        std::cout << "  模拟用户输入:\n";
        std::this_thread::sleep_for(1s);
        std::cout << "  收到用户输入，停止计数线程\n";
        
        counter.request_stop();
    }
    std::cout << "  计数线程已停止\n\n";
    
    // 7. jthread的优势总结
    std::cout << "  7. std::jthread的优势:\n";
    std::cout << "  - RAII风格的线程管理\n";
    std::cout << "  - 协作式线程终止机制\n";
    std::cout << "  - 简化了多线程代码的编写\n";
    std::cout << "  - 提高了多线程代码的安全性\n";
    std::cout << "  - 与现代C++的设计理念一致\n";
} 